﻿#define _CRT_SECURE_NO_WARNINGS

//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _a;
//	int _b;
//public:
//
//	Example(int x,int y)
//	{
//		_a = x;
//		_b = y;
//	}
//	//Print隐含的this指针由 Example* const this 变为 const Example* const this
//	void Print()const
//		//不希望函数内部修改成员变量
//		// 在参数列表后面加const
//	{
//		cout << "_a = " << _a << "," << "_ b = " << _b << endl;
//	}
//
//	//普通版本——用于普通对象
//	Example* operator&()
//	{
//		return this;//this指针就是当前对象地址
//		////也可以 return 假地址
//	}
//
//	//const版本——用于const修饰的对象
//	const Example* operator&()const
//		//Example* operator&()const  不可以这样写，返回就权限放大了
//	{
//		return this;//this指针就是当前对象地址
//		//也可以 return 假地址
//	}
//};
//
//int main()
//{
//	Example e1(1, 1);
//	const Example e2(2, 2);
//
//	e1.Print();
//	e2.Print();//Print成员函数如果不使用const修饰，就会存在权限放大
//
//	cout << &e1 << endl;
//	cout << &e2 << endl;//不显示写&运算符重载，也可以使用编译器自动生成的~
//}

//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _a;
//	int _b;
//public:
//
//	//构造函数写法一
//	/*Example(int x, int y)
//	{
//		_a = x;
//		_b = y;
//	}*/
//	//构造函数写法二（使用初始化列表）
//	//以⼀个冒号开始，接着是一个以逗号分隔的数据成员列表
//	// 每个"成员变量"后面跟一个放在括号中的初始值或表达式~
//	Example(int x,int y):_a(x),_b(y)
//	{
//		
//	}//依然写{}代表是函数
//
//	//Print隐含的this指针由 Example* const this 变为 const Example* const this
//	void Print()const
//		//不希望函数内部修改成员变量
//		// 在参数列表后面加const
//	{
//		cout << "_a = " << _a << "," << "_ b = " << _b << endl;
//	}
//
//};
//
//int main()
//{
//	Example e1(1, 4);
//	const Example e2(2, 3);
//
//	e1.Print();
//	e2.Print();//Print成员函数如果不使用const修饰，就会存在权限放大
//
//}


//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _a;
//	int _b;
//	const int _c;//const成员变量
//	int& _d;//引用成员变量
//public:
//	
//	/*Example(int x,int y,int z,int& m)
//	{
//		_a = x;
//		_b = y;
//		_c = z;
//		_d = m;
//	}*///err
//
//	Example(int x, int y, int z ,int& m) :_a(x), _b(y), _c(z), _d(m){ }
//	
//	//Print隐含的this指针由 Example* const this 变为 const Example* const this
//	void Print()const
//		//不希望函数内部修改成员变量
//		// 在参数列表后面加const
//	{
//		cout << "_a = " << _a  << ", _ b = " << _b << ", _c = " << _c << ", _d = " << _d << endl;
//	}
//
//};
//
//int main()
//{
//	int m = 0;
//	Example e1(1, 2, 3, m);
//	const Example e2(5, 6, 7, m);
//
//	e1.Print();
//	e2.Print();//Print成员函数如果不使用const修饰，就会存在权限放大
//
//}
//
//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _b = 30;
//	int _a = 10;//支持声明的时候给默认值（缺省值）
//	const int _c = 20;//const成员变量
//	int& _d;//引用成员变量
//public:
//	Example(int x, int y, int z, int& m) :_a(x), _c(z), _d(m) { }
//	/*Example(int x, int y, int z, int& m) : _b(y), _d(m)
//	{ 
//		_a = x;
//	}*/
//
//	//Print隐含的this指针由 Example* const this 变为 const Example* const this
//	void Print()const
//		//不希望函数内部修改成员变量
//		// 在参数列表后面加const
//	{
//		cout << "_a = " << _a << ", _ b = " << _b << ", _c = " << _c << ", _d = " << _d << endl;
//	}
//
//};
//
//int main()
//{
//	int m = 0;
//	Example e1(1, 2, 3, m);
//	const Example e2(5, 6, 7, m);
//
//	e1.Print();
//	e2.Print();//Print成员函数如果不使用const修饰，就会存在权限放大
//
//}


//#include<iostream>
//using namespace std;
//class A
//{
//public:
//	A(int a)
//		:_a1(a)
//		, _a2(_a1)
//	{}
//	void Print() {
//		cout << _a1 << " " << _a2 << endl;
//	}
//private:
//	int _a2 = 2;
//	int _a1 = 2;
//};
//int main()
//{
//	A aa(1);
//	aa.Print();
//}


//#include<iostream>
//using namespace std;
//class Example
//{
//private:
//	int _a;
//	int* _arr = (int*)malloc(80);//这里也可以给缺省值
//public:
//	Example(int a) :
//		_a(a),
//		_arr((int*)malloc(40))//开辟40个字节空间
//	{
//		//函数体内部检查处理
//		if (_arr == nullptr)//检查是否开辟成功
//		{
//			perror("malloc fail");
//			exit(1);
//		}
//		else
//		{
//			for (int i = 0; i < 10; i++)
//			{
//				_arr[i] = i + 1;//数据初始化
//			}
//		}
//	}
//};
//int main()
//{
//	Example(1);
//	return 0;
//}

//#include<iostream>
//using namespace std;
//class Example
//{
//private:
//	int _a;
//	int _b;
//public:
//	//explicit Example(int x);//加上不再支持隐式类型转换
//	Example(int x):_a(x)
//	{
//	}
//
//	//explicit Example(int x,int y);//加上不再支持隐式类型转换
//	Example(int x,int y):_a(x),_b(y)
//	{
//	}
//	//拷贝构造
//	Example(const Example& e)
//	{
//		_a = e._a;
//		_b = e._b;
//	}
//	int Get() const
//	{
//		return _a + _b;
//	}
//	void Print()
//	{
//		cout << "_a = " << _a << "," << "_b = " << _b << endl;
//	}
//};
//
//class C
//{
//public:
//	C(const Example& a)
//		:_c(a.Get())
//	{}//Example构造C的构造函数
//private:
//	int _c = 0;
//};
//int main()
//{
//	Example e1(1);
//	Example e2(2, 2);
//
//	Example e3 = 3;//连续构造+拷贝构造——>优化为直接构造
//
//	const Example& e4 = 4;//这里没有优化，不需要拷贝构造
//	//产生的临时对象具有常性，引用应该使用const修饰，避免权限放大
//
//	Example e5 = { 5,5 };//连续构造+拷贝构造——>优化为直接构造
//	//{} 形式，不可以写（ ），这个相当于逗号表达式，只得到了一个值
//
//	C c1 = e2;//e2隐式类型转换为c1对象
//	//连续构造+拷贝构造——>优化为直接构造
//
//	const C& c2 = e2;
//	//产生的临时对象具有常性，引用应该使用const修饰，避免权限放大
//	return 0;
//}

//#include<iostream>
//using namespace std;
//// 前置声明，都则A的友元函数声明编译器不认识B
//class B;
//class A
//{
//	// 友元声明
//	friend void func(const A& aa, const B& bb);
//	//友元函数可以在类定义的任何地方声明，不受类访问限定符限制
//private:
//	int _a1 = 1;
//	int _a2 = 2;
//};
//class B
//{
//private:
//	int _b1 = 3;
//	int _b2 = 4;
//	// 友元声明
//	friend void func(const A& aa, const B& bb);
//	//友元函数可以在类定义的任何地方声明，不受类访问限定符限制
//};
////⼀个函数可以是多个类的友元函数~
//void func(const A& aa, const B& bb)//A,B的友元函数
//{
//	cout << aa._a1 << endl;
//	cout << bb._b1 << endl;
//}
//int main()
//{
//	A aa;
//	B bb;
//	func(aa, bb);
//	return 0;
//}

#include<iostream>
using namespace std;
class A
{
	// 友元声明
	// 友元类
	friend class B;
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
public:
	void func1(const A& aa)
	{
		cout << aa._a1 << endl;
		cout << _b1 << endl;
	}
	void func2(const A& aa)
	{
		cout << aa._a2 << endl;
		cout << _b2 << endl;
	}
	//友元类中的成员函数都是另⼀个类的友元函数，都可以访问另⼀个类中的私有和保护成员~
private:
	int _b1 = 3;
	int _b2 = 4;
};
int main()
{
	A aa;
	B bb;
	bb.func1(aa);
	bb.func2(aa);
	return 0;
}